package com.tang.portal.facade.admin.sys;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tang.framework.core.domain.HttpResult;
import com.tang.framework.core.model.LoginUser;
import com.tang.common.model.req.ReqId;
import com.tang.common.constant.Constant;
import com.tang.common.model.req.ReqIds;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.tang.service.admin.domain.SysRole;
import com.tang.service.admin.domain.SysRoleMenu;
import com.tang.service.admin.model.req.ReqSysRole;
import com.tang.service.admin.model.req.ReqSysRoleAdd;
import com.tang.service.admin.model.res.ResSysRoleTableItem;
import com.tang.service.admin.model.res.ResSysRoleDetail;
import com.tang.service.admin.service.ISysRoleMenuService;
import com.tang.service.admin.service.ISysRoleService;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.BeanUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.tang.common.utils.excel.ExcelUtils.getStyleStrategy;
/**
 * @author tang jun liang
 * @Date ${gen.dateTime}
 */
@Service
public class SysRoleFacade {

    @Resource
    private ISysRoleService sysRoleService;


    @Resource
    private ISysRoleMenuService sysRoleMenuService;



    /**
     * 角色表删除
     * @param ids
     * @param currLoginUser
     * @return
     */
    public HttpResult<String> remove(ReqIds ids, LoginUser currLoginUser) {
        sysRoleService.removeBatchByIds(ids.getIds());
        return HttpResult.ok();
    }

    /**
     * 角色表详情
     * @param id
     * @param currLoginUser
     * @return
     */
    public HttpResult<ResSysRoleDetail> detail(ReqId id, LoginUser currLoginUser) {
        SysRole sysRole = sysRoleService.getById(id.getId());
        ResSysRoleDetail resSysRoleDetail = new ResSysRoleDetail();
        BeanUtils.copyProperties(sysRole, resSysRoleDetail);
        return HttpResult.ok(resSysRoleDetail);
    }

    /**
     * 角色表列表
     * @param reqSysRole
     * @param currLoginUser
     * @return
     */
    public HttpResult<IPage<ResSysRoleTableItem>> list(ReqSysRole reqSysRole, LoginUser currLoginUser) {
        IPage<ResSysRoleTableItem> page = sysRoleService.selectJoinListPage(
                new Page<>(reqSysRole.getPageNum(), reqSysRole.getPageSize()),
                ResSysRoleTableItem.class,
                new MPJLambdaWrapper<SysRole>()
                        .selectCollection(SysRoleMenu.class, ResSysRoleTableItem::getRoleMenuList)
                        .selectAll(SysRole.class)
                        .leftJoin(SysRoleMenu.class, SysRoleMenu::getRoleId, SysRole::getId)
                        .like(StringUtils.isNotBlank(reqSysRole.getRoleName()), SysRole::getRoleName, reqSysRole.getRoleName())
//                        .groupBy(SysRole::getId)
        );
        return HttpResult.ok(page);
    }

    /**
     * 新增角色表
     * @param sysRoleAdd
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public HttpResult<String> add(ReqSysRoleAdd sysRoleAdd) {
        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(sysRoleAdd, sysRole);
        sysRoleService.saveOrUpdate(sysRole);
        sysRoleMenuService.remove(sysRole.getId());
        List<SysRoleMenu> sysRoleMenuList = sysRoleAdd.getMenuIds().stream().map(item -> {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setMenuId(item);
            sysRoleMenu.setRoleId(sysRole.getId());
            return sysRoleMenu;
        }).collect(Collectors.toList());
        sysRoleMenuService.saveBatch(sysRoleMenuList);
        return HttpResult.ok();
    }

    /**
     * 更新角色表
     * @param sysRoleAdd
     * @return
     */
    public HttpResult<String> update(ReqSysRoleAdd sysRoleAdd) {
        return add(sysRoleAdd);
    }



    /**
     * 导出角色表表
     *
     * @param ids
     * @param httpServletResponse
     */
    @SneakyThrows
    public void export(ReqIds ids, HttpServletResponse httpServletResponse) {
        String fileName = URLEncoder.encode("角色表.xlsx", StandardCharsets.UTF_8);
        // 设置响应体
        httpServletResponse.setContentType("application/vnd.ms-excel");
        httpServletResponse.setCharacterEncoding("utf-8");
        httpServletResponse.setHeader("Content-disposition", "attachment;filename=" + fileName);
        List<SysRole> sysRoleList = sysRoleService
                .lambdaQuery()
                .in(!ids.getIds().isEmpty(), SysRole::getId, ids.getIds())
                .list();
        EasyExcel.write(httpServletResponse.getOutputStream(),SysRole.class)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .registerWriteHandler(getStyleStrategy())
                .sheet("角色表").doWrite(sysRoleList);
    }


    /**
     * 导入excel
     *
     * @param file
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public HttpResult<String> importExcel(MultipartFile file) throws IOException {
        InputStream inputStream = file.getInputStream();
        EasyExcel.read(inputStream, ReqSysRoleAdd.class, new AnalysisEventListener<ReqSysRoleAdd>() {
            final List<SysRole> sysRoleList = new ArrayList<>();
            @Override
            public void invoke(ReqSysRoleAdd sysRoleAdd, AnalysisContext analysisContext) {
                SysRole sysRole = new SysRole();
                BeanUtils.copyProperties(sysRoleAdd, sysRole);
                sysRoleList.add(sysRole);
                if (sysRoleList.size() == Constant.MAX_BATCH){
                    sysRoleService.saveBatch(sysRoleList);
                    sysRoleList.clear();
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                sysRoleService.saveBatch(sysRoleList);
            }
        });
        return HttpResult.ok();
    }

    /**
     * 导出模版
     * @param httpServletResponse
     */
    @SneakyThrows
    public void exportTemplate(HttpServletResponse httpServletResponse) {
        String fileName = URLEncoder.encode("角色表导入模版.xlsx", StandardCharsets.UTF_8);
        // 设置响应体
        httpServletResponse.setContentType("application/vnd.ms-excel");
        httpServletResponse.setCharacterEncoding("utf-8");
        httpServletResponse.setHeader("Content-disposition", "attachment;filename=" + fileName);
        EasyExcel.write(httpServletResponse.getOutputStream(), SysRole.class)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .registerWriteHandler(getStyleStrategy())
                .sheet("角色表").doWrite(List.of());
    }

}
